package com.rmuti.programming.editor;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PlatformUI;

import astexplorer.ASTMain;

import com.chula.testinterface.TestPlatform;
import com.chula.testinterface.TestResult;
import com.chula.testinterface.TestResultAdapter;
import com.rmuti.programming.callc.CallStudent;
import com.rmuti.programming.plugin.cplugin.HandleCPlugin;
import com.rmuti.programming.ui.ResultScore;

public class ProgrammingEditor implements IWorkbenchWindowActionDelegate {

	private Object dataTest;
	
	@Override
	public void run(IAction action) {
		System.out.println("execute event...");
		IWorkbench iWork = PlatformUI.getWorkbench();
		Display display = iWork.getDisplay();
		
//		c plugin
//		HandleCPlugin handleCPlugin = new HandleCPlugin();
//		handleCPlugin.createTempFolder();
//		handleCPlugin.copyStudentSourceToTemp();
//		handleCPlugin.createJNIFile();
//		handleCPlugin.compile();
//		handleCPlugin.setlLibraryPath();
//		
//		CallStudent student = new CallStudent();
//		System.out.println("********************** student "+student.getOutputStudent("1 90"));
		
		
//		getJavaProject();
		
//		System.out.println("name before : "+dataTest.getClass().getName());

		TestPlatform testPlatform = new TestPlatform(dataTest);
		TestResultAdapter testResult = testPlatform.testC();
		System.out.println(testResult.getPoint());

		ResultScore resultScore = new ResultScore(display);
		resultScore.displayUI(testResult);


	}

	@Override
	public void selectionChanged(IAction arg0, ISelection arg1) {

	}

	@Override
	public void dispose() {

	}

	@Override
	public void init(IWorkbenchWindow arg0) {

	}

	private void getJavaProject() {
		IProject project = ResourcesPlugin.getWorkspace().getRoot()
				.getProject("hello");
		try {
			printProjectInfo(project);
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	private void printProjectInfo(IProject project) throws CoreException,
			JavaModelException {
//		System.out.println("Working in project " + project.getName());
		// Check if we have a Java project
		if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
			IJavaProject javaProject = JavaCore.create(project);
			printPackageInfos(javaProject);
		}
	}

	private void printPackageInfos(IJavaProject javaProject)
			throws JavaModelException {
		IPackageFragment[] packages = javaProject.getPackageFragments();		
		for (IPackageFragment mypackage : packages) {
			// Package fragments include all packages in the
			// classpath
			// We will only look at the package from the source
			// folder
			// K_BINARY would include also included JARS, e.g.
			// rt.jar
			if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) {
//				System.out.println("Package " + mypackage.getElementName());
				printICompilationUnitInfo(mypackage);
			}

		}
	}

	private void printICompilationUnitInfo(IPackageFragment mypackage)
			throws JavaModelException {
		for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
//			try {
//				getClass().getClassLoader()
//				   ClassLoader loader = new CustomClassLoader(getClass().getClassLoader(), requestor.getResults());
//				   String className = CharOperation.toString(unit.getPackageName()) + "." + 
//				   new String(unit.getMainTypeName());
//				   Class clazz = loader.loadClass(className);
//				   Method m = clazz.getMethod("main",new Class[] {String[].class});
//				   m.invoke(clazz,new Object[] { new String[0] });
//				}
//				catch (Exception e) {
//				   e.printStackTrace();
//				}
			
			ASTMain main = new ASTMain();
			main.compileAndRun((org.eclipse.jdt.internal.compiler.env.ICompilationUnit) unit);
			dataTest = main.getDataTest();
			
//			printCompilationUnitDetails(unit);
			
//			Compiler compiler = new Compiler(new NameEnvironmentImpl(unit),
//                    DefaultErrorHandlingPolicies.proceedWithAllProblems(),
//                    settings,requestor,new DefaultProblemFactory(Locale.getDefault()));
//           compiler.compile(new ICompilationUnit[] { unit });			
		}
	}

//	static private class CustomClassLoader extends ClassLoader {
//	    private Map classMap;
//
//	    CustomClassLoader(ClassLoader parent,List classesList) {
//	       this.classMap = new HashMap();
//	       for (int i = 0; i < classesList.size(); i++) {
//	          ClassFile classFile = (ClassFile)classesList.get(i);
//	          String className = CharOperation.toString(classFile.getCompoundName());
//	          this.classMap.put(className,classFile.getBytes());
//	       }
//	    }
//	    public Class findClass(String name) throws ClassNotFoundException {
//	       byte[] bytes = (byte[]) this.classMap.get(name);
//	       if (bytes != null)
//	          return defineClass(name, bytes, 0, bytes.length);
//
//	       return super.findClass(name);
//	    }
//	}	
	
	private void printIMethods(ICompilationUnit unit) throws JavaModelException {
		IType[] allTypes = unit.getAllTypes();
		for (IType type : allTypes) {
			printIMethodDetails(type);
		}
	}

	private void printCompilationUnitDetails(ICompilationUnit unit)
			throws JavaModelException {
		System.out.println("Source file " + unit.getElementName());	
		Document doc = new Document(unit.getSource());
//		System.out.println("Has number of lines: " + doc.getNumberOfLines());
		printIMethods(unit);
	}

	private void printIMethodDetails(IType type) throws JavaModelException {
//		Class<? extends IType> objType = type.getClass();
//		try {
//			IType obj = objType.newInstance();
//		} catch (InstantiationException | IllegalAccessException e) {
//			e.printStackTrace();
//		}
		IMethod[] methods = type.getMethods();
		for (IMethod method : methods) {
			if (method.isMainMethod()) {				
				System.out.println("Method name " + method.getElementName());
				System.out.println("Signature " + method.getSignature());
				System.out.println("Return Type " + method.getReturnType());
			}
		}
	}

}
